﻿using System;
using System.Runtime.Caching;

namespace ComTools.Helpers
{
    /// <summary>
    /// 缓存操作
    /// </summary>
    /// <summary>
    /// 该类主要用来缓存数据
    /// </summary>
    public class MemoryCacheHelper
    {
        /// <summary>
        /// 同步锁对象
        /// </summary>
        Object LOCK = new Object();

        /// <summary>
        /// 单例模式
        /// </summary>
        private MemoryCacheHelper() { }

        /// <summary>
        /// 单例
        /// </summary>
        private static MemoryCacheHelper instance = new MemoryCacheHelper();

        /// <summary>
        /// 获取缓存管理实例
        /// </summary>
        public static MemoryCacheHelper Instance
        {
            get
            {
                return instance;
            }
        }

        /// <summary>
        /// 获取缓存值
        ///     
        ///     如果出现异常或者没有找到，则返回传入对象的默认值
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>缓存值</returns>
        public T GetValue<T>(string key)
        {
            lock (LOCK)
            {
                try
                {
                    var value = MemoryCache.Default.Get(key);
                    if (value != null)
                    {
                        var ret = value is T == false ? default(T) : (T)value;
                        return ret;
                    }
                    else
                    {
                        return default(T);
                    }
                }
                catch (NotSupportedException)
                {
                    return default(T);
                }
                catch (ArgumentNullException)
                {
                    return default(T);
                }
            }
        }

        /// <summary>
        /// 获取缓存值
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>缓存值</returns>
        public object GetValue(string key)
        {
            lock (LOCK)
            {
                try
                {
                    return MemoryCache.Default.Get(key);
                }
                catch (NotSupportedException)
                {
                    return default(object);
                }
                catch (ArgumentNullException)
                {
                    return null;
                }
            }
        }


        /// <summary>
        /// 获取缓存值并删除
        /// 
        ///     如果出现异常或者没有找到，则返回传入对象的默认值
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>缓存值</returns>       
        public T GetValueNotRetain<T>(string key)
        {
            lock (LOCK)
            {
                try
                {
                    var value = MemoryCache.Default.Remove(key);
                    if (value != null)
                    {
                        var ret = value is T == false ? default(T) : (T)value;
                        return ret;
                    }
                    else
                    {
                        return default(T);
                    }
                }
                catch (NotSupportedException)
                {
                    return default(T);
                }
                catch (ArgumentNullException)
                {
                    return default(T);
                }
            }
        }

        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <param name="seconds">缓存时间--秒</param>
        /// <returns>设置结果</returns>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <exception cref="Exception"></exception>
        public void SetValue(string key, object value, int seconds)
        {
            try
            {
                lock (LOCK)
                {
                    if (seconds > double.MaxValue) throw new ArgumentOutOfRangeException("seconds");
                    var offset = new DateTimeOffset(DateTime.Now);
                    offset = offset.AddSeconds(seconds);
                    MemoryCache.Default.Set(key, value, offset);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key">键</param>
        public void Delete(string key)
        {
            lock (LOCK)
            {
                try
                {
                    if (MemoryCache.Default.Contains(key))
                    {
                        MemoryCache.Default.Remove(key);
                    }
                }
                catch { }
            }
        }
    }
}
